home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 03 - 1987 / 03.10 Oct 87 / RomRef sources / PasROMRef sources / PasRomRef.c next >
Encoding:
Text File  |  1986-08-17  |  20.5 KB  |  743 lines  |  [TEXT/MEDT]

  1. /*  A ROM Reference Desk Accessory  */
  2. /*          Frank Alviani           */
  3. /*           Version 1.1            */
  4. /*          Pascal Format           */
  5. /*       8:36:39 PM  8/5/86         */
  6. /*                                  */
  7. /*  Thanks to Don Melton for making */
  8. /*  this a whole bunch easier!      */
  9.  
  10. #Options R=4 Z K
  11. #include <MacDefs.h>
  12. #include <QuickDraw.h>
  13. #include <Control.h>
  14. #include <TextEdit.h>
  15. #include <Dialog.h>
  16. #include <Menu.h>
  17. #include <Events.h>
  18. #include <Desk.h>
  19. #include <DeskAccessory.c>
  20. #include <Resource.h>
  21.  
  22. /* MODIFIED DEFINITIONS
  23.  
  24. *** IMPORTANT *** Other alternate elements of the OpParamType union structure
  25. are not defined here!!!
  26.  
  27. The CntrlParam structure also must be defined because OSIO.h is not included.
  28. However, it remains unaltered. */
  29.  
  30. #define OsType long
  31. union __OP
  32.     { 
  33.     struct
  34.         {
  35.         short menuID;
  36.         short menuItem;
  37.         } menuData;
  38.     Ptr event;
  39.     };
  40.  
  41. #define OpParamType union __OP
  42.  
  43. struct __CP
  44.     {
  45.     struct __CP *ioLink;
  46.     short ioType;
  47.     short ioTrap;
  48.     Ptr ioCmdAddr;
  49.     ProcPtr ioCompletion;
  50.     short ioResult;
  51.     char *ioNamePtr;
  52.     short ioVRefNum;
  53.     short ioRefNum;
  54.     short CSCode;
  55.     OpParamType csp;
  56.     };
  57.  
  58. #define CntrlParam struct __CP
  59.  
  60. typedef struct
  61.     {
  62.     char typeName[4];
  63.     } ResType;
  64.  
  65. typedef struct {
  66. long        scrapSize;
  67. Handle      scrapHandle;
  68. short       scrapCount;
  69. short       scrapState;
  70. char        *scrapName;
  71. } ScrapStuff, *ScrapStuffPtr;
  72.  
  73. #define NULL 0
  74. #define FALSE 0
  75. #define TRUE 1
  76. #define geneva      3
  77. #define NAMES_IN_BOX 7
  78. #define TIX ((long *) 0x16A)
  79.  
  80. #define ACCEPT 1
  81. #define ACCEPT_CONT 2
  82. #define APPEND 3
  83. #define APPEND_CONT 4
  84. #define CANCEL 5
  85. #define NBOX 7
  86. #define SBAR 8
  87.  
  88. #define FRONT_WINDOW -1
  89.  
  90. /* SETUP DA HEADER AND GLUE ROUTINES
  91. *** IMPORTANT *** Invoke this macro BEFORE declaring any global variables or
  92. defining any Mac C functions!!!
  93.  
  94. Macro parameters:
  95.     1       Name of desk accessory (enclose text in single quotes)
  96.     2       Resource ID of desk accessory (12-31 inclusive)
  97.     3       Flags
  98.     4       Delay
  99.     5       Event Mask
  100.     6       Request for global variable allocation: NeedGlobals or NoGlobals
  101. */
  102.  
  103. #asm
  104.  
  105.  DeskAccessory 'Pas ROM Ref',12,$0400,0,$0142,NeedGlobals
  106.  
  107. #endasm
  108.  
  109. /* GLOBAL VARIABLES */
  110. short           ownedID;
  111. short           no_casting;     /* 0=typecast  1=don't typecast */
  112. short           mem_mash;       /* 1=include "mashes memory" comment */
  113. short           selection;
  114. MenuHandle      hRRMenu;
  115. DialogPtr       abtDlgPtr, mgrDlgPtr, rtnDlgPtr;
  116. long            lastClick;
  117. short           lastPick;       /* used in double-click test */
  118. short           data_refNum;    /* vol ref num for data resource file */
  119. short           old_v;          /* for arrow-scrolling in dialog */
  120. ControlHandle   rtnScrlH, namScrlH; /* scroll bar in routine window */
  121. ControlHandle   vScrlH;         /* "generic" for ModalDialog filterProc */
  122. Handle          abTblH;         /* handle to abbreviation table */
  123. TEHandle        hTE;            /* for names selection routine */
  124. Rect            textR, TERect;
  125. char            call[256];      /* sample here */
  126. ScrapStuffPtr   sInfo;
  127.  
  128. /*~Open/Close/Control~ --- Open Routine --- */
  129. short open(pb, dce)
  130. CntrlParam      *pb;
  131. DeviceControl   *dce;
  132. {
  133. GrafPtr         oldPort;
  134. short           item, type, err, def_vol;
  135. ControlHandle   ctlH;
  136. Ptr             tPtr;
  137. short           pbCall();
  138.  
  139.     ownedID = 0xC000 - (32 * (1 + dce->dCtlRefNum));
  140.     dce->dCtlMenu = ownedID;
  141.  
  142.     if (!dce->dCtlWindow)
  143.       { hRRMenu = GetMenu(ownedID);
  144.         HNoPurge(hRRMenu);
  145.  
  146.         if (!(mgrDlgPtr = (DialogPtr) NewPtr(sizeof(DialogRecord))))
  147.           return -1;
  148.         mgrDlgPtr = GetNewDialog(ownedID, mgrDlgPtr, FRONT_WINDOW);
  149.         GetDItem(mgrDlgPtr, SBAR, &type, &namScrlH, &textR);  /* scrollbar */
  150.         namScrlH = NewControl(mgrDlgPtr, &textR, "\px", FALSE, 0, 0, 0,
  151.                               scrollBarProc, 0);
  152.         
  153.         if (!(rtnDlgPtr = (DialogPtr) NewPtr(sizeof(DialogRecord))))
  154.           return -1;
  155.         rtnDlgPtr = GetNewDialog(ownedID+1, rtnDlgPtr, FRONT_WINDOW);
  156.         
  157.         GetDItem(rtnDlgPtr, SBAR, &type, &rtnScrlH, &textR);  /* scrollbar */
  158.         rtnScrlH = NewControl(rtnDlgPtr, &textR, "\px", FALSE, 0, 0, 0,
  159.                               scrollBarProc, 0);
  160.         
  161.         GetDItem(rtnDlgPtr, NBOX, &type, &ctlH, &textR);  /* get scrollBOX rect */
  162.         TERect = textR;
  163.         InsetRect(&TERect, 2, 2);
  164.  
  165.         if (!(abtDlgPtr = (DialogPtr) NewPtr(sizeof(DialogRecord))))
  166.           return -1;
  167.         abtDlgPtr = GetNewDialog(ownedID+2, abtDlgPtr, FRONT_WINDOW);
  168.  
  169.         /* open data file */ 
  170.         if ((data_refNum = OpenResFile("\pRom Reference Data")) == -1)
  171.           return -1;
  172.  
  173.         if ((abTblH = GetResource('ROMA', 1)) == NULL)   /* get abb. table */
  174.           return -1;
  175.  
  176.         no_casting = 0; mem_mash = 0;
  177.         activate();
  178.       }
  179.     return 0;
  180. }
  181.  
  182. /* --- Close --- */
  183. short close(pb, dce)
  184. CntrlParam      *pb;
  185. DeviceControl   *dce;
  186. {
  187.     deActivate();
  188.     ReleaseResource(hRRMenu);
  189.     ReleaseResource(abTblH);
  190.     DisposeDialog(mgrDlgPtr);
  191.     DisposeDialog(rtnDlgPtr);
  192.     DisposeDialog(abtDlgPtr);
  193.     dce->dCtlWindow = (WindowPtr) NULL;
  194.     CloseResFile(data_refNum);  /* close data file */
  195.     return 0;
  196. }
  197.  
  198. /* --- Control --- */
  199. short control(pb, dce)
  200. CntrlParam      *pb;
  201. DeviceControl   *dce;
  202. {
  203. EventRecord     *theEvent;
  204.  
  205.     switch (pb->CSCode)
  206.       { case accEvent:
  207.           theEvent = (EventRecord *) pb->csp.event;
  208.           if (theEvent->what ==activateEvt)
  209.               if (theEvent->modifiers & activeFlag)
  210.                 activate();
  211.           break;
  212.         case accMenu:
  213.           doMenu(pb, pb->csp.menuData.menuItem, dce);
  214.           break;
  215.     }
  216.   return 0;
  217. }
  218.  
  219. activate()
  220. {
  221.   (*hRRMenu)->menuID = ownedID;
  222.   InsertMenu(hRRMenu, 0);
  223.   DrawMenuBar();
  224. }
  225.  
  226. deActivate()
  227. {
  228.     DeleteMenu(ownedID);
  229.     DrawMenuBar();
  230. }
  231.  
  232. /*~Menu Stuff~ --- Handle Menu Invocations --- */
  233. doMenu(pb, menuItem, dce)
  234. CntrlParam      *pb;
  235. short           menuItem;
  236. DeviceControl   *dce;
  237. {
  238. short       theItem;
  239. GrafPtr     tGPtr;
  240.  
  241.     switch (menuItem)
  242.       { case 1:     /* ABOUT */
  243.           dce->dCtlFlags &= 0xFBFF; /* clear dCtlEnable */
  244.           dce->dCtlFlags ^= 0x4000; /* set dNeedLock */
  245.  
  246.           ((WindowPeek) abtDlgPtr)->windowKind = 2;   /* dialogkind */
  247.           ShowWindow(abtDlgPtr);
  248.           BringToFront(abtDlgPtr);
  249.           SetPort(abtDlgPtr);
  250.           ModalDialog(NULL, &theItem);
  251.           ((WindowPeek) abtDlgPtr)->windowKind = dce->dCtlRefNum;
  252.           HideWindow(abtDlgPtr);
  253.  
  254.           dce->dCtlFlags ^= 0x0400; /* set dCtlEnable */
  255.           dce->dCtlFlags &= 0xBFFF; /* clear dNeedLock */
  256.           break;
  257.         case 2:     /* LOOKUP CALLS */
  258.           dce->dCtlFlags &= 0xFBFF; /* clear dCtlEnable */
  259.           dce->dCtlFlags ^= 0x4000; /* set dNeedLock */
  260.  
  261.           findRtn(dce);
  262.  
  263.           dce->dCtlFlags ^= 0x0400; /* set dCtlEnable */
  264.           dce->dCtlFlags &= 0xBFFF; /* clear dNeedLock */
  265.           break;
  266.         case 3:     /* DISABLE TYPECASTING */
  267.           if (no_casting)       /* was NO, now YES */
  268.             { no_casting = 0;
  269.               CheckItem(hRRMenu, 3, FALSE);
  270.             }
  271.           else
  272.             { no_casting = 1;
  273.               CheckItem(hRRMenu, 3, TRUE);
  274.             }
  275.           break;
  276.         case 4:     /* INCLUDE 'MASHES MEMORY' COMMENT */
  277.           if (mem_mash)
  278.             { mem_mash = 0;
  279.               CheckItem(hRRMenu, 4, FALSE);
  280.             }
  281.           else
  282.             { mem_mash = 1;
  283.               CheckItem(hRRMenu, 4, TRUE);
  284.             }
  285.           break;
  286.         case 5:     /* CLOSE */
  287.           close(pb, dce);
  288.           break;
  289.       }
  290.     HiliteMenu(0);
  291. }
  292.  
  293. /*~Lookup Code~ --- Heart of the DA --- */
  294. findRtn(dce)
  295. DeviceControl   *dce;
  296. {
  297. short       the_manager, item, base_res_no, pick;
  298. long        scrap_err, call_len;
  299. short       BoxPick();
  300.  
  301.   get_mgr:
  302.     /* use "select manager" dialog */
  303.     dce->dCtlWindow = 0;
  304.     /* get titles for selected manager */
  305.     SetPort(mgrDlgPtr);
  306.     item =  BoxPick(mgrDlgPtr, namScrlH, 99, &the_manager, &base_res_no);
  307.     HideWindow(mgrDlgPtr);
  308.     if (item == CANCEL) return;
  309.       
  310.     /* get titles for selected manager */
  311.     SetPort(rtnDlgPtr);
  312.     item =  BoxPick(rtnDlgPtr, rtnScrlH, the_manager+1, &pick, &base_res_no);
  313.     if (item < CANCEL )
  314.       { expandCall(base_res_no+pick, &call_len);
  315.         if (call_len)
  316.           { if (item < APPEND )
  317.               { ZeroScrap();
  318.                 scrap_err = PutScrap((long) call_len, 'TEXT', call);
  319.               }
  320.             else
  321.               AppendScrap((long) call_len, 'TEXT', call);
  322.           }
  323.       }
  324.  
  325.     ((WindowPeek) rtnDlgPtr)->windowKind = dce->dCtlRefNum;
  326.     HideWindow(rtnDlgPtr);
  327.  
  328.     if (item == ACCEPT_CONT || item == APPEND_CONT)     /* keep it up! */
  329.       goto get_mgr;
  330. }
  331.  
  332. /* --- assumes port is properly set before entry --- */
  333. /* --- returns item_no from modal dialog box --- */
  334. short BoxPick(dPtr, scrlH, resNo, sel, base)
  335. DialogPtr       dPtr;
  336. ControlHandle   scrlH;
  337. short           resNo;
  338. short           *sel;   /* zero-based! */
  339. short           *base;
  340. {
  341. short       filter();
  342. Handle      nameListH;      /* handle to names-list resource */
  343. long        call_len, nameList_len, ticks;
  344. short       res_ct, done, item, l_no, sel_st, sel_en;
  345. Point       pt;
  346.  
  347.     if ((nameListH = GetResource('ROMN', resNo)) == NULL)
  348.       { SysBeep(60);
  349.         return CANCEL;
  350.       }
  351.     nameList_len = SizeResource(nameListH);
  352.     HLock(nameListH);
  353.     res_ct = *((short *) *nameListH);   /* ct of call resources */
  354.     *base = *((short *) *nameListH+1);  /* starting call res # is 2nd short! */
  355.  
  356.     hTE = TENew(&TERect, &TERect);
  357.     (*hTE)->txFont = geneva;
  358.     (*hTE)->crOnly = -1;        /* CR breaks only */
  359.     (*hTE)->txSize = 12;
  360.     TESetText(*nameListH+4, nameList_len-4, hTE);
  361.     TECalText(hTE);
  362.     TESetSelect((*hTE)->lineStarts[0], (*hTE)->lineStarts[1], hTE);
  363.  
  364.     ((WindowPeek) dPtr)->windowKind = 2;   /* dialogkind */
  365.     ShowWindow(dPtr);
  366.     BringToFront(dPtr);
  367.     FrameRect(&textR.top);
  368.     TEUpdate(&TERect.top, hTE);
  369.     TEActivate(hTE);
  370.     ShowControl(scrlH);
  371.     SetCtlMin(scrlH, 0);
  372.     if ((*hTE)->nLines > NAMES_IN_BOX)   /* set up scrollbar */
  373.       SetCtlMax(scrlH, (*hTE)->nLines-NAMES_IN_BOX);
  374.     else
  375.       SetCtlMax(scrlH, 0);
  376.     SetCtlValue(scrlH, 0);
  377.  
  378.     done = FALSE; selection=0;
  379.     old_v = 0;
  380.     vScrlH = scrlH;
  381.     while (!done)
  382.       { ModalDialog(filter, &item);   /* filter for keystrokes only */
  383.         switch (item)
  384.           { case ACCEPT:
  385.             case ACCEPT_CONT:
  386.             case APPEND:
  387.             case APPEND_CONT:
  388.             case CANCEL:
  389.               done = TRUE;
  390.               break;
  391.             case NBOX:
  392.               GetMouse(&pt);
  393.               ticks = *TIX;
  394.               l_no = (pt.v - textR.top) / (*hTE)->lineHeight; /* relative line# */
  395.               selection = GetCtlValue(scrlH) + l_no;
  396.               if ((lastClick + 30) > ticks)
  397.                 { item = ACCEPT;     /* double click in same item */
  398.                   done = TRUE;
  399.                   break;
  400.                 }
  401.               sel_st = (*hTE)->lineStarts[selection];
  402.               if (selection >= res_ct)
  403.                 sel_en = 32767;
  404.               else
  405.                 sel_en = (*hTE)->lineStarts[selection + 1];
  406.               TESetSelect(sel_st, sel_en, hTE);
  407.               TEActivate(hTE);
  408.               lastPick = selection;
  409.               lastClick = ticks;
  410.               break;
  411.             case SBAR:
  412.               nameScroll(dPtr);
  413.               break;
  414.           }
  415.       }
  416.     TEDispose(hTE);
  417.     HUnlock(nameListH);
  418.     ReleaseResource(nameListH);
  419.     *sel = selection;
  420.     return item;
  421. }
  422.  
  423. /* --- Append to scrap, updating scrapCount - Memory Only -- */
  424. /* assumes only 1 data type in desk scrap */
  425. AppendScrap(len, type, str)
  426. long        len;
  427. long        type;   /* 4-char string */
  428. char        *str;
  429. {
  430. long            sSize, dSize;
  431.  
  432.         sInfo = (ScrapStuffPtr)0x960;
  433.         if (sInfo->scrapState <= 0) return;     /* can't do anything */
  434.         sSize = GetHandleSize(sInfo->scrapHandle);
  435.         dSize = *((long *)(*sInfo->scrapHandle) + 1);   /* get existing len */
  436.         SetHandleSize(sInfo->scrapHandle, sSize + len); /* make room */
  437.         *((long *)(*sInfo->scrapHandle) + 1) = dSize + len;
  438.         BlockMove(str, (*sInfo->scrapHandle + 8 + dSize), len);
  439. }
  440.  
  441. /*~Scrolling~ --- Filter Events, Handle Scrolling, etc. --- */
  442. short filter(dPtr, ePtr, item)
  443. DialogPtr       dPtr;
  444. EventRecord     *ePtr;
  445. short           *item;
  446. {
  447. #asm
  448.     link        A6,#0           ;no locals
  449.     movem.l     D1-D2,-(sp)     ;save
  450.     move.l      16(A6),D0
  451.     move.l      12(A6),D1
  452.     move.l      8(A6),D2
  453.     jsr         md_filter       ;call C routine
  454.     movem.l     (SP)+,D1-D2
  455.     unlk        A6
  456.     move.l      (SP)+,A0        ;return addr
  457.     add.l       #12,sp
  458.     move.b      D0,(SP)         ;return condition
  459.     jmp         (A0)
  460. #endasm
  461. }
  462.  
  463. /* uses global "vScrlH" to access vertical scrollbar in MD window */
  464. short md_filter(dPtr, ePtr, item)
  465. DialogPtr       dPtr;
  466. EventRecord     *ePtr;
  467. short           *item;
  468. {
  469. short           part, new_v, i, j, k, dV;
  470. short           sel_st, sel_en, delta;
  471. char            ch, ch2, key;
  472. Ptr             tPtr, base;
  473. short           nameScroll();
  474.  
  475.     switch(ePtr->what)
  476.       { case mouseDown:
  477.           return FALSE;       /* handle normally */
  478.           break;
  479.         case autoKey:
  480.         case keyDown:   /* select by 1st letter, cursor keys, etc. */
  481.           ch = ePtr->message & 0xFF;
  482.           if (ch==0x03 || ch==0x0D)     /* enter or return */
  483.             { *item = 1;    /* accept */
  484.               return TRUE;
  485.             }
  486.           /* check for up/down arrow keys */
  487.           if (old_v <= GetCtlMax(vScrlH))   /* don't update if in last paneful */
  488.             old_v = GetCtlValue(vScrlH);
  489.           j = GetCtlMax(vScrlH);
  490.           TEDeactivate(hTE);
  491.           TESetSelect(0, 0, hTE);
  492.           key = (ePtr->message & 0xFF00) >> 8;
  493.           if (key == 0x4D) /* up arrow on Mac+ */
  494.             { i = old_v-1;
  495.               if (i < 0) i = 0;
  496.               goto qa1;
  497.             }
  498.           if (key == 0x48) /* down arrow on Mac+ */
  499.             { i = old_v + 1;
  500.               goto qa1;
  501.             }
  502.           /* look up 1st entry starting with given key or higher */
  503.           ch &= (~0x20);   /* force uppercase */
  504.           HLock((*hTE)->hText);     /* lock text for examination */
  505.           base = *(*hTE)->hText;
  506.           for (i=0;i<j;i++)
  507.             { tPtr = base + (*hTE)->lineStarts[i];
  508.               ch2 = *tPtr & (~0x20);    /* 1st char of line, upper-cased */
  509.               if (ch2 >= ch)            /* found desired line */
  510.                 break;
  511.             }
  512.           HUnlock((*hTE)->hText);
  513.         qa1:
  514.           if (i <= j)   /* in normal range, scroll */
  515.             { dV = (old_v - i) * (*hTE)->lineHeight;
  516.               SetCtlValue(vScrlH, i);
  517.               TEScroll(0, dV, hTE);
  518.             }
  519.           
  520.           if (i >= GetCtlMax(vScrlH)+NAMES_IN_BOX)
  521.             { i = GetCtlMax(vScrlH)+NAMES_IN_BOX-1;   /* can't go too far */
  522.               sel_en = 32767;
  523.               k = (*hTE)->nLines-1;
  524.               sel_st = (*hTE)->lineStarts[k];
  525.             }
  526.           else
  527.             { sel_en = (*hTE)->lineStarts[i+1];
  528.               sel_st = (*hTE)->lineStarts[i];
  529.             }
  530.           TESetSelect(sel_st, sel_en, hTE);
  531.           old_v = i;
  532.           selection = i;    /* in global so ACCEPT works */
  533.           TEActivate(hTE);
  534.           return TRUE;
  535.           break;
  536.         default:
  537.           return FALSE;
  538.           break;
  539.       }
  540. }
  541.  
  542. void nameScroll(dPtr)
  543. DialogPtr   dPtr;
  544. {
  545. short           part, new_part, old_v, new_v, dV;
  546. ControlHandle   ctlH;
  547. Point           pt;
  548. void            scroll_up(), scroll_dn();
  549.  
  550.     GetMouse(&pt);
  551.     if (part = FindControl(&pt, dPtr, &ctlH))
  552.       { old_v = GetCtlValue(ctlH);
  553.         switch (part)
  554.           { case inThumb:
  555.               new_part = TrackControl(ctlH, &pt, NULL);
  556.               if (new_part == part)     /* redraw box */
  557.                 { TEDeactivate(hTE);
  558.                   new_v = GetCtlValue(ctlH);
  559.                   dV = (old_v - new_v) * (*hTE)->lineHeight;
  560.                   TEScroll(0, dV, hTE);
  561.                 }
  562.               break;
  563.             case inUpButton:
  564.               TrackControl(ctlH, &pt, scroll_up);
  565.               break;
  566.             case inDownButton:
  567.               TrackControl(ctlH, &pt, scroll_dn);
  568.               break;
  569.             case inPageUp:
  570.               new_v = old_v - (NAMES_IN_BOX-1);
  571.               if (old_v-new_v < 0)
  572.                 { dV = old_v * (*hTE)->lineHeight;    /* stop at beginning */
  573.                   SetCtlValue(ctlH, 0);
  574.                 }
  575.               else
  576.                 { dV = (NAMES_IN_BOX-1) * (*hTE)->lineHeight;
  577.                   SetCtlValue(ctlH, new_v);
  578.                 }
  579.               TEScroll(0, dV, hTE);
  580.               break;
  581.             case inPageDown:
  582.               new_v = old_v + (NAMES_IN_BOX-1);
  583.               if (new_v > GetCtlMax(ctlH))
  584.                 { dV = -(GetCtlMax(ctlH) - old_v) * (*hTE)->lineHeight;
  585.                   SetCtlValue(ctlH, GetCtlMax(ctlH));
  586.                 }
  587.               else
  588.                 { dV = -(NAMES_IN_BOX-1) * (*hTE)->lineHeight;
  589.                   SetCtlValue(ctlH, new_v);
  590.                 }
  591.               TEScroll(0, dV, hTE);
  592.               break;
  593.           }
  594.         selection = new_v = GetCtlValue(ctlH);
  595.         TESetSelect((*hTE)->lineStarts[new_v], (*hTE)->lineStarts[new_v+1], hTE);
  596.         TEActivate(hTE);
  597.       }
  598. }
  599.  
  600. void my_scroll_up(theControl, part)
  601. ControlHandle   theControl;
  602. short           part;
  603. {
  604. short   v;
  605.  
  606.     if (part == inUpButton)   /* */
  607.       { v = GetCtlValue(theControl);
  608.         if (v == 0) return;
  609.         SetCtlValue(theControl, v-1);
  610.         TEScroll(0, (*hTE)->lineHeight, hTE);
  611.       }
  612.     return;
  613. #asm
  614. scroll_up:
  615.     MOVE.L  (SP)+,A0        ;RETURN
  616.     MOVE.W  (SP)+,D1        ;PART
  617.     MOVE.L  (SP)+,D0        ;CTL HANDLE
  618.     MOVE.L  A0,-(SP)
  619.     MOVEM.L A3-A4/D3-D7,-(SP)
  620.     JSR     my_scroll_up
  621.     MOVEM.L (SP)+,A3-A4/D3-D7
  622.     RTS
  623. #endasm
  624. }
  625.  
  626. void my_scroll_dn(theControl, part)
  627. ControlHandle   theControl;
  628. short           part;
  629. {
  630. short   v;
  631.  
  632.     if (part == inDownButton)
  633.       { v = GetCtlValue(theControl);
  634.         if (v == GetCtlMax(theControl)) return;
  635.         SetCtlValue(theControl, v+1);
  636.         TEScroll(0, -(*hTE)->lineHeight, hTE);
  637.       }
  638.     return;
  639. #asm
  640. scroll_dn:
  641.     MOVE.L  (SP)+,A0        ;RETURN
  642.     MOVE.W  (SP)+,D1        ;PART
  643.     MOVE.L  (SP)+,D0        ;CTL HANDLE
  644.     MOVE.L  A0,-(SP)
  645.     MOVEM.L A3-A4/D3-D7,-(SP)
  646.     JSR     my_scroll_dn
  647.     MOVEM.L (SP)+,A3-A4/D3-D7
  648.     RTS
  649. #endasm
  650. }
  651.  
  652. /*~Prototype Expansion~ --- Resource -> usable call --- */
  653. void expandCall(res_no, len)
  654. short       res_no;
  655. long        *len;
  656. {
  657. Handle      rHndl;
  658. short       i, j, isVar, cast;
  659. long        rSize;
  660. unsigned char   *rPtr, ch, abb[32];
  661.  
  662.     if ((rHndl = GetResource('ROMC', res_no)) == NULL)
  663.       { SysBeep(30);
  664.          *len = 0; *call = NULL;
  665.          return;
  666.       }
  667.     rSize = SizeResource(rHndl);
  668.     HLock(rHndl);
  669.     rPtr = (unsigned char *) *rHndl;
  670.     HLock(abTblH);      /* lock abb. table */
  671.  
  672.     /* deal with "memory mashing" */
  673.     j=0; isVar = 0; cast = NULL;
  674.     if (mem_mash) 
  675.       { if (*(rPtr++))   /* this one moves memory */
  676.           appStr("{ mashes memory } ", call, &j)
  677.       }
  678.     else
  679.       rPtr += 1;    /* just skip flag */
  680.  
  681.     for (i=1;i<rSize;i++)    /* copy into output, expanding abbreviations */
  682.       { if (*rPtr < 0x80)   /* normal char */
  683.           { /* end of param? */
  684.             if (*rPtr == ',' || *rPtr == ')' || *rPtr == ' ' || *rPtr == '=')
  685.               { if (no_casting == NULL && cast)
  686.                   { call[j++] = ':';
  687.                     findabb(cast, abb);     /* lookup typecast */
  688.                     appStr(abb, &(call[j]), &j);
  689.                     cast = NULL;    /* done with it */
  690.                   }
  691.               }
  692.             call[j++] = *(rPtr++);
  693.             continue;
  694.           }
  695.         if (no_casting == NULL)
  696.           { if (*rPtr >= 0xC0)   /* "var" */
  697.               { cast = *rPtr - 0x40;
  698.                 appStr("VAR ", &(call[j]), &j);
  699.               }
  700.             else
  701.               cast = *rPtr;
  702.           }
  703.         rPtr += 1;
  704.       }
  705.  
  706.     appStr(";\n", &(call[j]), &j);
  707.     *len = j;
  708.     HUnlock(rHndl);
  709.     HUnlock(abTblH);
  710.     ReleaseResource(rHndl);
  711. }
  712.  
  713. void appStr(src, target, tLen)
  714. char    *src;       /* string copied FROM, null-terminated */
  715. char    *target;    /* string appended TO */
  716. short   *tLen;      /* initial length of target; updated */
  717. {
  718. long    ct=0;
  719. Ptr     tp;
  720.  
  721.     tp = src;
  722.     while (*(tp++))
  723.       ct++;
  724.     BlockMove(src, target, ct);
  725.     *tLen = *tLen + ct;
  726. }
  727.  
  728. void findabb(c, dest)
  729. unsigned char   c;
  730. unsigned char   *dest;
  731. {
  732. short   i,j;
  733. Ptr     tPtr;
  734.  
  735.     tPtr = *abTblH;
  736.     j = c - 0x80;
  737.     for (i=0;i<j;i++)
  738.       while (*(tPtr++));
  739.     while (*tPtr)
  740.       *(dest++) = *(tPtr++);
  741.     *dest = NULL;
  742. }
  743.